home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Magazin: Amiga-CD 1995 October
/
Amiga-CD 1995 #10.iso
/
amiga-magazin
/
farbdithering
/
listing3
< prev
next >
Wrap
Text File
|
1995-08-30
|
3KB
|
87 lines
void DitherFSLevels(Picture *Pict,LONG Levels)
{
WORD *temp,*this,*next,*swap;
LONG x,y,v,r,pixel,index;
LONG range;
// Die Anzahl der Graustufen um 1 vermindern
Levels--;
// Dieser Bruchwert wird gleich zum Runden verwendet
range = 255 / Levels;
// Zwischenspeicher beschaffen
if(temp = (WORD *)AllocVec(sizeof(WORD)*2 *
(1 + Pict -> Width + 1)),MEMF_ANY))
{
memset(temp,0,sizeof(WORD) * 2 * (1 + Pict -> Width + 1)));
// Die beiden Zeilenpuffer werden initialisiert
this = &temp[1]; next = &temp[1 + (1 + Pict -> Width + 1)];
for(y = 0 ; y < Pict -> Height ; y++)
{ // In Zeilen mit ungerader Nummer von rechts nach links
if(y & 1)
{ for(x = Pict -> Width - 1 ; x >= 0 ; x--)
{ // Position des Pixels bestimmen
index = x + y * Pict -> Width;
// Helligkeitswert berechnen (0 = Min, 255 = Max)
v = (Pict -> Red[index] + Pict -> Green[index] +
Pict -> Blue[index]) / 3;
v = this[x] + v; // Fehlerwert aufschlagen
// Der Helligkeitswert wird auf den zulässigen
// Bereich beschränkt
if(v > 255) pixel = 255;
else
{ if(v < 0) pixel = 0;
else pixel = v;
}
// Die Helligkeit des Pixels wird abgerundet
pixel = (pixel / range) * range;
// Der "Fehler" ist die Differenz zwischen dem
// berechneten Pixelwert und dem zu zeichnenden
r = v - pixel;
this[x - 1] += (7 * r) / 16;
next[x + 1] += (3 * r) / 16;
next[x ] += (5 * r) / 16;
next[x - 1] += ( r) / 16;
SetAPen(RPort,pixel); WritePixel(RPort,x,y);
}
}
else
{ // In Zeilen mit gerader Nummer von links nach rechts
for(x = 0 ; x < Pict -> Width ; x++)
{ index = x + y * Pict -> Width;
v = (Pict -> Red[index] + Pict -> Green[index] +
Pict -> Blue[index]) / 3;
v = this[x] + v;
if(v > 255) pixel = 255;
else
{ if(v < 0) pixel = 0;
else pixel = (v / range) * range;
}
r = v - pixel;
this[x + 1] += (7 * r) / 16;
next[x - 1] += (3 * r) / 16;
next[x ] += (5 * r) / 16;
next[x + 1] += ( r) / 16;
SetAPen(RPort,pixel); WritePixel(RPort,x,y);
}
}
// Der Inhalt der folgenden in die aktuelle Zeile schieben
swap = this; this = next; next = swap;
// Die folgende Zeile wird gelöscht
memset(next,0,sizeof(WORD) * Pict -> Width);
}
FreeVec(temp);
}
}